<#--  Check if Catalog Name has been specified
 * @param attr
 *  attribute data type with {name, type, facet } info}
<#if (Catalog.name?length < 1) > <#assign catalogName = TriaGram + Prefix + "Catalog">
<#else> <#assign catalogName = Catalog.name> </#if>
-->
<#--  Adds a tk_xxx attribue Get/Set functions
 * @param attr
 *  attribute data type with {name, type, facet } info}
-->
<#macro DOXY_COMMENTS  func >
 /**
 * ${func.name}
 <#list func.Args as Arg>
 * @param ${Arg.name}
 *
 <#lt></#list> <#--   end of Arg loop-->*/
</#macro>

<#--  Adds a tk_xxx attribue Get/Set functions
 * @param attr
 *  attribute data type with {name, type, facet } info}
-->
<#macro FUNC_COMMON  func className="">

  ${func.qual} ${func.rtype} ${className}${func.name} ( <#rt>
	 <#list func.Args as Arg>
	 		<#lt> ${Arg.qual}  ${Arg.type}  ${Arg.varqual}  ${Arg.name} ${Arg.def}<#if Arg_has_next>,</#if> <#rt>
	 </#list>
	 <#lt> ) ${func.type} <#t>
	 </#macro>

<#--  Adds a tk_xxx attribue Get/Set functions
 * @param attr
 *  attribute data type with {name, type, facet } info}
-->
<#macro FUNC_DECL  func >
	 <@FUNC_COMMON func /> <#lt><#if func.pvirtual == "y" > =0 </#if> ;
</#macro>

<#--  Adds a tk_xxx attribue Get/Set functions
 * @param attr
 *  attribute data type with {name, type, facet } info}
-->
<#macro FUNC_DEF  func className>
  <#assign classNamePreFix=className + "::" />
  <@FUNC_COMMON func classNamePreFix />

  {
		  return ${func.rtype}  ;
  }
</#macro>


<#--  Adds a tk_xxx attribue Get/Set functions
 * @param attr
 *  attribute data type with {name, type, facet } info}
-->
<#function GetCAADataType tk_type list>

<#assign h = {"tk_specobject":"CATISpecObject", "tk_integer":"int"}>

<#return returnValue> ${h[tk_type]}

</#function>

<#assign CAA_TypesFwDecl = { "tklist_integer":"CATRawCollint", 
				 "tklist_double":"CATRawColldouble", 
				 "tklist_string":"CATListValCATUnicodeString", 
				 "tklist_specobject":"CATListValCATISpecObject_var", 
				 "tklist_component":"CATListValCATISpecObject_var", 
				 "tk_string":"CATUnicodeString", 
				 "tk_specobject":"CATISpecObject_var", 
				 "tk_component":"CATISpecObject_var", 
				 "tk_param":"CATICkeParm_var" } >

<#assign CAA_Include = { "tklist_integer":"CATListOfInt", 
			 "tklist_double":"CATListOfDouble", 
			 "tklist_string":"CATListOfCATUnicodeString", 
			 "tklist_specobject":"CATLISTV_CATISpecObject", 
			 "tklist_component":"CATLISTV_CATISpecObject", 
			 "tk_string":"CATUnicodeString", 
			 "tk_specobject":"CATISpecObject", 
			 "tk_component":"CATISpecObject", 
			 "tk_param":"CATICkeParm" } >

<#assign Types = [
	{"name":"double"	, "type":"double"			, "IDLtype":"double"		,"tk_type":"tk_param_real"	, "prefix":"d"		, "sp":""	 , "IDLPrefix":" id"	, "IDLGetFix":"d"	, "setPrefix":" id"	, "qual":""}
	{"name":"double"	, "type":"double"			, "IDLtype":"double"		,"tk_type":"tk_param_length"	, "prefix":"d"		, "sp":""	 , "IDLPrefix":" id"	, "IDLGetFix":"d"	, "setPrefix":" id"	, "qual":""}
	{"name":"double"	, "type":"double"			, "IDLtype":"double"		,"tk_type":"tk_param_angle"	, "prefix":"d"		, "sp":""	 , "IDLPrefix":" id"	, "IDLGetFix":"d"	, "setPrefix":" id"	, "qual":""}
	{"name":"bool"		, "type":"CATBoolean"		, "IDLtype":"boolean"		,"tk_type":"tk_param_boolean"	, "prefix":"b"		, "sp":""	 , "IDLPrefix":" ib"	, "IDLGetFix":"b"	, "setPrefix":" ib"	, "qual":""}
	{"name":"string"	, "type":"CATUnicodeString"	, "IDLtype":"CATBSTR"		,"tk_type":"tk_param_string"	, "prefix":"Str"	, "sp":""	 , "IDLPrefix":" iStr"	, "IDLGetFix":"Str"	, "setPrefix":"& iStr"	, "qual":"const"}
	{"name":"int"		, "type":"int"				, "IDLtype":"short"			,"tk_type":"tk_integer"		, "prefix":"n"		, "sp":""	 , "IDLPrefix":" in"	, "IDLGetFix":"n"	, "setPrefix":" in"	, "qual":""}
	{"name":"double"	, "type":"double"			, "IDLtype":"double"		,"tk_type":"tk_double"		, "prefix":"d"		, "sp":""	 , "IDLPrefix":" id"	, "IDLGetFix":"d"	, "setPrefix":" id"	, "qual":""}
	{"name":"bool"		, "type":"CATBoolean"			, "IDLtype":"boolean"		,"tk_type":"tk_boolean"		, "prefix":"b"		, "sp":""	 , "IDLPrefix":" ib"	, "IDLGetFix":"b"	, "setPrefix":" ib"	, "qual":""}
	{"name":"Spec"		, "type":"CATISpecObject"		, "IDLtype":"CATIAReference","tk_type":"tk_specobject"	, "prefix":"spSpec"	, "sp":"_var"	 , "IDLPrefix":" ipSpec", "IDLGetFix":"spSpec"	, "setPrefix":"* ipSpec", "qual":""}
	{"name":"comp"		, "type":"CATISpecObject"		, "IDLtype":"CATIAReference","tk_type":"tk_component"	, "prefix":"spSpec"	, "sp":"_var"	 , "IDLPrefix":" ipSpec", "IDLGetFix":"spSpec"	, "setPrefix":"* ipSpec", "qual":""}
	{"name":"string"	, "type":"CATUnicodeString"		, "IDLtype":"CATBSTR"		,"tk_type":"tk_string"		, "prefix":"Str"	, "sp":""	 , "IDLPrefix":" iStr"	, "IDLGetFix":"Str"	, "setPrefix":"& iStr"	, "qual":"const"}
	{"name":"list_int"	, "type":"CATListOfInt"			, "IDLtype":"CATSafeArrayVariant","tk_type":"tklist_integer"	, "prefix":"List"	, "sp":""	 , "IDLPrefix":" in"	, "IDLGetFix":"List"	, "setPrefix":" in"	, "qual":"const"}
	{"name":"list_double", "type":"CATListOfDouble"		, "IDLtype":"CATSafeArrayVariant","tk_type":"tklist_double"	, "prefix":"List"	, "sp":""	 , "IDLPrefix":" id"	, "IDLGetFix":"List"	, "setPrefix":" id"	, "qual":"const"}
	{"name":"list_spec"	, "type":"CATListValCATISpecObject_var"	, "IDLtype":"CATSafeArrayVariant","tk_type":"tklist_specobject"	, "prefix":"ListSpec"	, "sp":""	 , "IDLPrefix":" ipSpec", "IDLGetFix":"List"	, "setPrefix":"* ipSpec", "qual":"const"},
	{"name":"list_component", "type":"CATListValCATISpecObject_var"	, "IDLtype":"CATSafeArrayVariant","tk_type":"tklist_component" 	, "prefix":"ListSpec"	, "sp":""    	 , "IDLPrefix":" ipSpec", "IDLGetFix":"ListSpec", "setPrefix":"* ipSpec", "qual":"const"},
	{"name":"list_string"	, "type":"CATListOfCATUnicodeString"	, "IDLtype":"CATSafeArrayVariant","tk_type":"tklist_string" 	, "prefix":"ListStr"	, "sp":""    	 , "IDLPrefix":" iStr"	, "IDLGetFix":"ListStr"	, "setPrefix":"& iStr"	, "qual":"const"}
]  >

<#assign ListTypes = [
	{"name":"list_int"	, "type":"CATListOfInt"			, "tk_type":"tklist_integer"	, "prefix":"List"	, "sp":""	, "IDLPrefix":" in"	, "setPrefix":" in", "qual":""}
	{"name":"list_double"	, "type":"CATListOfDouble"		, "tk_type":"tklist_double"	, "prefix":"List"	, "sp":""	, "IDLPrefix":" id"	, "setPrefix":" id", "qual":""}
	{"name":"list_boolean"	, "type":"CATBoolean"			, "tk_type":"tklist_boolean"	, "prefix":"List"	, "sp":""	, "IDLPrefix":" ib", "setPrefix":" ib", "qual":""}
	{"name":"list_spec"	, "type":"CATListValCATISpecObject_var" , "tk_type":"tklist_specobject"	, "prefix":"List"	, "sp":""	,  "IDLPrefix":" ipSpec","setPrefix":"* ipSpec", "qual":"const"}
	{"name":"list_component", "type":"CATListValCATISpecObject_var" , "tk_type":"tklist_component"	, "prefix":"ListSpec"	, "sp":""	 , "IDLPrefix":" ipSpec"	,  "setPrefix":"* ipSpec", "qual":"const"}
	{"name":"list_string"	, "type":"CATListOfCATUnicodeString"	, "tk_type":"tklist_string"	, "prefix":"ListStr"	, "sp":""	 , "IDLPrefix":" iStr"	, "setPrefix":"& iStr", "qual":"const"}
]  >

<#assign ckeParam = [
	{"arg":1, "type":"double"		, "tk_type":"tk_param_length" 	, "prefix":"d"	, "IDLPrefix":" in", "conversion":"1000", "setPrefix":"", "qual":""}
	{"arg":2, "type":"double"		, "tk_type":"tk_param_angle" 	, "prefix":"d"	, "IDLPrefix":" in", "conversion":"57.295779513082323", "setPrefix":"", "qual":""}
	{"arg":3, "type":"double"		, "tk_type":"tk_param_real" 	, "prefix":"d"	, "IDLPrefix":" in", "conversion":"", "setPrefix":"", "qual":""}
	{"arg":4, "type":"CATBoolean"		, "tk_type":"tk_param_boolean"  , "prefix":"b"	, "IDLPrefix":" in", "conversion":"", "setPrefix":"", "qual":""}
	{"arg":5, "type":"CATUnicodeString"	, "tk_type":"tk_param_string" 	, "prefix":"Str", "IDLPrefix":" in", "conversion":"", "setPrefix":"&", "qual":"const"}
]  >

<#--  Forward declaration of all class data types used for Attributes in Interface.h file
-->

<#macro CAA_FORWARD_DECL  attribs >
<#assign fwIncl = [] >
<#list attribs as attr>
	<#assign dataType = attr.type >
	<#if attr.type?starts_with("tk_param") >
		<#assign dataType = "tk_param" >
	</#if>
	<#if dataType != "tk_integer" && dataType != "tk_boolean" && dataType != "tk_double" >
		<#assign attrFwIncl = CAA_TypesFwDecl[dataType] >
		<#if fwIncl?seq_contains(attrFwIncl) == false >
			<#assign fwIncl = fwIncl + [ attrFwIncl ] >
		</#if >
	</#if>
</#list>

<#list fwIncl as f>
class ${f} ;
</#list>

</#macro>


<#macro CAA_INCLUDE_HEADERS  attribs >
<#assign fwIncl = [] >
<#list attribs as attr>
	<#assign dataType = attr.type >
	<#if attr.type?starts_with("tk_param") >
		<#assign dataType = "tk_param" >
	</#if>
	<#if dataType != "" && dataType != "tk_integer" && dataType != "tk_boolean" && dataType != "tk_double" >
		<#assign attrFwIncl = CAA_Include[dataType] >
		<#if fwIncl?seq_contains(attrFwIncl) == false >
			<#assign fwIncl = fwIncl + [ attrFwIncl ] >
		</#if >
	</#if>
</#list>

<#list fwIncl as f>
#include "${f}.h" 
</#list>

</#macro>

<#--  Adds a tk_xxx attribue Get function DECLaration
 * @param attr
 *  attribute data type with {name, type, facet } info}
-->
<#macro ADD_GET_FUNC_DECL_COMMON  attr clsName="" fqual="" ftype ="">
<#list Types as x>
<#if ( attr.type?length == 0 ) >
 /**
 * ${clsName}${attr.name}
 * @return
 * S_OK if successfull else E_FAIL.
 */
 ${fqual} HRESULT ${clsName}${attr.name}() ${ ftype}
<#break>
<#elseif x.tk_type == attr.type>
 /**
 * ${clsName}Get${attr.name}
 * @param o${x.prefix}${attr.name}
 *
	<#if attr.type?starts_with("tk_param") >
 * Value returned is in <#if attr.type == "tk_param_length" > mm <#elseif attr.type == "tk_param_angle" > degrees </#if> .
	</#if>
 * @return
 * S_OK if successfull else E_FAIL.
 */
 ${fqual} HRESULT ${clsName}Get${attr.name}( ${x.type}${x.sp}   &  o${x.prefix}${attr.name}) ${ ftype}
	<#if attr.type?starts_with("tk_param") >
 /**
 * ${clsName}Get${attr.name}
 * @param o${x.prefix}${attr.name}
 *
 * @return
 * S_OK if successfull else E_FAIL.
 */
 ${fqual} HRESULT ${clsName}Get${attr.name}( CATICkeParm_var  &  ospParm${attr.name}) ${ ftype}
	</#if>
<#break></#if></#list>
</#macro>

<#--  Adds a tk_xxx attribue Set function DECLaration
 * @param attr
 *  attribute data type with {name, type, facet } info}
-->
<#macro ADD_SET_FUNC_DECL_COMMON  attr clsName="" fqual="" ftype ="">
<#list Types as x>
<#if x.tk_type == attr.type>
 /**
 * ${clsName}Set${attr.name}
 * @param ${x.prefix}${attr.name}
 *
<#if attr.type?starts_with("tk_param") >
* Units is <#if attr.type == "tk_param_length" > mm <#elseif attr.type == "tk_param_angle" > degrees </#if> .
</#if>
 * @return
 * S_OK if successfull else E_FAIL.
 */
 ${fqual} HRESULT ${clsName}Set${attr.name}( ${x.qual}  ${x.type}  ${x.setPrefix}${attr.name})  ${ftype}
</#if></#list>
</#macro>

<#--  Adds a tk_xxx attribue Get/Set functions DECLaration
 * @param attr
 *  attribute data type with {name, type, facet } info}
-->
<#macro ADD_FUNC_DECL  attr clsName="" pvirtual ="y">
<#if pvirtual == "y">
<#lt><@ADD_GET_FUNC_DECL_COMMON attr clsName  "virtual" "=0 ;" /><#lt>
<#lt><@ADD_SET_FUNC_DECL_COMMON attr clsName  "virtual" "=0 ;" /><#lt>
<#else>
<#lt><@ADD_GET_FUNC_DECL_COMMON attr clsName "" " ;" /><#lt>
<#lt><@ADD_SET_FUNC_DECL_COMMON attr clsName "" " ;" /><#lt>
</#if> 
</#macro>

<#macro GET_SPEC_ATTR_ACCESS attr attrPrefix LT="" >
		// Gets a pointer on CATISpecAttrAccess
		CATISpecAttrAccess_var spiSpecAttrAccess = this ;
		if ( NULL_var == spiSpecAttrAccess)
		{
			return E_FAIL ;
		}

		// Gets a pointer on the ${LT}::${attr.name} attribute
		CATISpecAttrKey *piSpecAttrKey = spiSpecAttrAccess->GetAttrKey("${attrPrefix}${attr.name}");
		if ( NULL == piSpecAttrKey )
		{
			return E_FAIL ;
		}
</#macro>

<#--  Adds a tk_xxx attribue Get/Set functions DEFinition
 * @param attr
 *  attribute data type with {name, type, facet } info}
-->
<#macro ADD_FUNC_DEF  attr clsName="" >
<#list Types as t>  <#if t.tk_type == attr.type> <#assign x = t> <#break></#if></#list><#t>

<@ADD_GET_FUNC_DECL_COMMON attr className + "::" />
{
	<@GET_SPEC_ATTR_ACCESS attr.name "" />

    o${x.setPrefix}${attr.name} = spiSpecAttrAccess->GetSpecObject(piSpecAttrKey);

    return rc ;
}
<@ADD_SET_FUNC_DECL_COMMON attr className + "::" />
{
	<@GET_SPEC_ATTR_ACCESS attr.name LT="" />

        spiSpecAttrAccess->SetSpecObject(piSpecAttrKey, ${x.setPrefix}${attr.name});

	${TriaGram}ReleasePtr(piSpecAttrKey);
    }

    return rc ;
}
</#macro>

<#--  adds a tk_list(tk_xxx) attribue Get/Set functions DECLaration
 * @param attr
 *  LIST attribute data type with {name, type, facet } info}
-->
<#macro ADD_LIST_FUNC_DECL  attr clsName="", pvirtual ="y">
<#lt><#list ListTypes as t>  <#if t.tk_type == attr.type> <#assign x = t> <#break></#if></#list>
 /**
 * ${clsName}Get${attr.name}
 * @param o${x.prefix}${attr.name}
 *
 * @return
 * S_OK if successfull else E_FAIL.
 */
 virtual HRESULT ${clsName}Get${attr.name}( ${x.type}  &  o${x.prefix}${attr.name})   <#if pvirtual == "y" > =0 </#if> ;

 /**
 * ${clsName}Get${attr.name}
 * @param i${x.prefix}${attr.name}
 *
 * @return
 * S_OK if successfull else E_FAIL.
 */
 virtual HRESULT ${clsName}Set${attr.name}( const ${x.type}  &  i${x.prefix}${attr.name}) <#if pvirtual == "y" > =0 </#if> ;

 <#if x.type == "CATListValCATISpecObject_var">
 /**
 * ${clsName}Add${attr.name}
 * @param ipSpec${attr.name}
 *
 * @return
 * S_OK if successfull else E_FAIL.
 */
 virtual HRESULT ${clsName}Add${attr.name}( const CATISpecObject_var & ispSpec${attr.name}, int inIndex =0 ) <#if pvirtual == "y" > =0 </#if> ;

 /**
 * ${clsName}Remove${attr.name}
 * @param ipSpec${attr.name}
 *
 * @return
 * S_OK if successfull else E_FAIL.
 */
 virtual HRESULT ${clsName}Remove${attr.name}( const CATISpecObject_var & ispSpec${attr.name}) <#if pvirtual == "y" > =0 </#if> ;
 </#if>
</#macro>

<#-- Add Attribute code/macro for CatalogMain.cpp file.
-->
<#macro ADD_ATTRIBUTE specObject attr  attrPrefix>
  		<#if attr.type?starts_with("tklist")>
		ADD_ATTRIBUTE("${attrPrefix}${attr.name}", tk_list( ${attr.type?replace('list', '')} ), ${attr.facet} );
		<#elseif attr.type?starts_with("tk_param") >
		ADD_ATTRIBUTE("${attrPrefix}${attr.name}", tk_component, ${attr.facet} );
		<#elseif ( attr.type?length > 0 ) >
		ADD_ATTRIBUTE("${attrPrefix}${attr.name}", ${attr.type}, ${attr.facet} );
		</#if>
</#macro>

<#-- Adds Attribute to an OSM file
* For tk_list attributes - remove string "tklist" from  type - except for tklist_integer !!!
-->
<#macro ADD_OSM_ATTRIBUTE attr  attrPrefix>
	<#assign facet = attr.facet?replace('sp_', '') >
  	<#if attr.type?starts_with("tklist")>
	  <#if attr.type == "tklist_integer">
		int ${attrPrefix}${attr.name} #list #${facet?lower_case}
	  <#else>
		${attr.type?replace('tklist_', '')} ${attrPrefix}${attr.name} #list #${facet?lower_case}
	  </#if>
	<#elseif attr.type?starts_with("tk_param") >
		component ${attrPrefix}${attr.name} #${facet?lower_case}
	<#elseif attr.type == "tk_integer" >
		int ${attrPrefix}${attr.name} #${facet?lower_case}
	<#else>
		${attr.type?replace('tk_', '')} ${attrPrefix}${attr.name} #${facet?lower_case}
	</#if>
</#macro>


<#--  Creats CATDlg DataType and variable name hashTable
 * @param attribs
 *  HashTable as given in tdd file
-->
<#macro CPP_ATTRIB_DATA_TYPE_FORWARD_DECL attribs >
<#assign row =  -1  >
<#list attribs as attr>
<#if  (attr.UI?length > 0 ) >
<#assign row =  row + 1 >
<#switch attr.UI>
<#case "BiList">
<#case "List">
<#break>
</#switch>
</#if>
</#list>
</#macro>
